package com.fyyg.wechat.util.wechat;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Random;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.binary.Base64;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;

import com.fyyg.common.exceptions.StandardException;
import com.fyyg.wechat.util.HttpClientUtils;
import com.google.common.base.Joiner;
import com.google.common.base.Splitter;
import com.google.common.base.Strings;
import com.google.common.collect.Lists;

public class StringHelper
{

	public static String decode(String... strs)
    {
        if (strs == null || strs.length == 0)
        {
            return null;
        }
        String base = strs[0];
        String result = base;

        int i = 0;
        boolean b = false;
        boolean nv = true;

        for (String s : strs)
        {

            if (i == 0)
            {
                i++;
                continue;
            }
            if (nv)
            {
                b = StringUtils.equals(base, s);
                nv = false;
            }
            else
            {
                if (b)
                {
                    result = s;
                    break;
                }
                nv = true;
            }

        }

        return result;

    }

    public static String convertStreamToBase64(InputStream is)
    {
        byte[] b = HttpClientUtils.loadStream(is);

        String r = Base64.encodeBase64String(b);
        return r;
    }

    public static InputStream convertBase64ToStream(String base64)
    {
        byte[] b = Base64.decodeBase64(base64);

        ByteArrayInputStream bis = new ByteArrayInputStream(b);

        return bis;
    }

    public static String join(List<String> list, String separator)
    {
        if (CollectionUtils.isEmpty(list))
        {
            return null;
        }
        return Joiner.on(separator).skipNulls().join(list);
    }

    private static Random random = null;

    public static boolean booleanValue(String bool)
    {
        if (StringUtils.equalsIgnoreCase("true", bool))
        {
            return true;
        }
        if (StringUtils.equalsIgnoreCase("yes", bool))
        {
            return true;
        }
        if (StringUtils.equalsIgnoreCase("open", bool))
        {
            return true;
        }
        if (StringUtils.equalsIgnoreCase("active", bool))
        {
            return true;
        }
        if (StringUtils.equalsIgnoreCase("enable", bool))
        {
            return true;
        }
        if (StringUtils.equalsIgnoreCase("1", bool))
        {
            return true;
        }
        return false;
    }

    public static boolean isEmpty(String str)
    {
        if (str == null)
            return true;
        String a = trim(str);

        if (Strings.isNullOrEmpty(a))
        {
            return true;
        }

        return false;
    }

    /**
     * 去除字符串中所包含的空格（包括:空格(全角，半角)、制表符、换页符等）
     * 
     * @param s
     * @return
     */
    public static String removeAllBlank(String s)
    {
        String result = "";
        if (null != s && !"".equals(s))
        {
            result = s.replaceAll("[　*| *| *|\\s*]*", "");
        }
        return result;
    }

    /**
     * 去除字符串中头部和尾部所包含的空格（包括:空格(全角，半角)、制表符、换页符等）
     * 
     * @param s
     * @return
     */
    public static String trim(String s)
    {
        String result = "";
        if (null != s && !"".equals(s))
        {
            result = s.replaceAll("^[　*| *| *|\\s*]*", "")
                    .replaceAll("[　*| *| *|\\s*]*$", "");
        }
        return result;
    }

    private static Random getRandomInstance()
    {
        if (random == null)
        {
            random = new Random(new Date().getTime());
        }
        return random;
    }

    public static String format(String str, String... param)
    {
        if (str == null)
        {
            return str;
        }

        StringBuffer sb = new StringBuffer(str);
        List<Integer> tagIndexList = Lists.newArrayList();

        int c = -1;

        while ((c = StringUtils.indexOf(str, '?', c)) >= 0)
        {
            tagIndexList.add(c++);
        }
        for (int i = tagIndexList.size(); i > 0; i--)
        {
            int idx = tagIndexList.get(i - 1);
            if (param == null || i > param.length)
            {
                sb.delete(idx, idx + 1);
            }
            else
            {
                String str2 = param[i - 1];
                sb.replace(idx, idx + 1, str2 == null ? "" : str2);
            }
        }
        return sb.toString();

    }

    public static String formatWithPattern(String str, String pattern,
            String... param)
    {
        if (str == null)
        {
            return str;
        }

        /*
         * StringBuffer sb = new StringBuffer(str); List<Integer> tagIndexList =
         * Lists.newArrayList();
         * 
         * int c = -1*pattern.length();
         * 
         * while((c=StringUtils.indexOf(str, pattern,c+pattern.length()))>=0){
         * tagIndexList.add(c); c=c+pattern.length(); } for (int i =
         * tagIndexList.size(); i >0; i--) { int idx = tagIndexList.get(i-1);
         * if(param == null || i > param.length){ sb.delete(idx,
         * idx+pattern.length()); }else{ sb.replace(idx, idx+pattern.length(),
         * param[i-1]); } }
         */

        String _ptnStr = Matcher.quoteReplacement(pattern);

        Pattern _ptn = Pattern.compile(_ptnStr);
        Matcher _mcr = _ptn.matcher(str);
        StringBuffer sb = new StringBuffer();

        int current = 0;

        while (_mcr.find())
        {
            String replacement = param == null || param.length <= current
                    ? StringUtils.EMPTY : param[current++];
            _mcr.appendReplacement(sb, replacement);
        }

        _mcr.appendTail(sb);

        return sb.toString();

    }

    public static String word2(String wordPattern, Object... params)
    {

        List<String> list = Lists.newArrayList();
        if (ArrayUtils.isNotEmpty(params))
        {
            for (Object object : params)
            {
                if (object == null)
                {
                    list.add(StringUtils.EMPTY);
                    continue;
                }
                list.add(object.toString());
            }
        }
        return word(wordPattern, list.toArray(new String[]
        {}));
    }

    public static String word(String wordPattern, String... params)
    {
        Pattern pattern = Pattern.compile("\\{\\d\\d*\\}");
        Matcher m = pattern.matcher(wordPattern);
        StringBuffer sb = new StringBuffer();

        while (m.find())
        {
            String g = m.group();
            String idxStr = g.substring(1, g.length() - 1);
            int idx = Integer.valueOf(idxStr);
            String replacement = null;
            if (params == null || params.length <= idx)
            {
                replacement = StringUtils.EMPTY;
            }
            else
            {
                Object obj = params[idx];
                if (obj == null)
                {
                    replacement = StringUtils.EMPTY;
                }
                else
                {
                    if (obj instanceof BigDecimal)
                    {
                        replacement = HttpClientUtils
                                .formatBigDeciam((BigDecimal) obj, "###.##");
                    }
                    else
                    {
                        replacement = obj.toString();
                    }
                }
            }

            String valueReplacement = replacement.replaceAll("\\\\", "\\\\\\\\")
                    .replaceAll("\\$", "\\\\\\$");
            m.appendReplacement(sb, valueReplacement);
        }

        m.appendTail(sb);

        return sb.toString();
    }

    public static String formatWithPattern(String str,
            Map<String, String> paramMap)
    {
        if (str == null)
        {
            return str;
        }

        Set<String> keySet = paramMap.keySet();

        StringBuffer sb = new StringBuffer();

        for (String key : keySet)
        {
            System.out.println("使用key>" + key);
            String value = paramMap.get(key);
            Pattern _ptn = Pattern.compile(key);
            Matcher _mcr = _ptn.matcher(str);
            while (_mcr.find())
            {
                System.out.println(_mcr.start());
                _mcr.appendReplacement(sb, value);
            }

            System.out.println("生成>" + sb.toString());

            // String currentPattern = _ptn.pattern();
            // System.out.println(currentPattern);

        }

        return sb.toString();
    }

    public static String getChinese()
    {
        String str = null;
        int highPos, lowPos;
        Random random = getRandomInstance();
        highPos = (176 + Math.abs(random.nextInt(39)));
        lowPos = 161 + Math.abs(random.nextInt(93));
        byte[] b = new byte[2];
        b[0] = (new Integer(highPos)).byteValue();
        b[1] = (new Integer(lowPos)).byteValue();
        try
        {
            str = new String(b, "GBK");
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }
        return str;
    }

    public static String getFixedLengthChinese(int length)
    {
        String str = "";
        for (int i = length; i > 0; i--)
        {
            str = str + StringHelper.getChinese();
        }
        return str;
    }

    public static String getRandomLengthChiness(int start, int end)
    {
        String str = "";
        int length = new Random().nextInt(end + 1);
        if (length < start)
        {
            str = getRandomLengthChiness(start, end);
        }
        else
        {
            for (int i = 0; i < length; i++)
            {
                str = str + getChinese();
            }
        }
        return str;
    }

    public static String getRandomUUID()
    {
        UUID uuid = UUID.randomUUID();
        String str = uuid.toString();
        // 去掉"-"符号
        String temp = str.substring(0, 8) + str.substring(9, 13)
                + str.substring(14, 18) + str.substring(19, 23)
                + str.substring(24);
        return temp;
    }

    public static String getShortRandomUUID()
    {
        String r = getRandomUUID();
        return ShortTextUtil.get12Char(r);
    }

    public static String decimalToString(BigDecimal dec, int scale,
            String defaultIfNull)
    {
        if (dec == null)
            return defaultIfNull;
        return dec.setScale(scale, RoundingMode.HALF_UP).toString();
    }

    public static String intToString(Integer i, String defaultIfNull)
    {
        if (i == null)
            return defaultIfNull;
        return String.valueOf(i);
    }

    public static String regexReplace(String value, String regexQuery,
            String regexReplace)
    {
        if (Strings.isNullOrEmpty(value))
        {
            return value;
        }

        Pattern pattern = Pattern.compile(regexQuery);
        String result = pattern.matcher(value).replaceAll(regexReplace);
        return result;
    }

    public static String getRegexMatch(String value, String regexQuery)
    {
        if (Strings.isNullOrEmpty(value))
        {
            return value;
        }

        Pattern pattern = Pattern.compile(regexQuery);
        System.out.println(pattern.matcher(value).groupCount());
        String result = pattern.matcher(value).group();
        return result;
    }

    public static int getByteLength(String value)
    {
        if (Strings.isNullOrEmpty(value))
        {
            return 0;
        }

        return value.getBytes().length;
    }

    public static String truncateStringWithByte(String str, int length)
    {
        if (Strings.isNullOrEmpty(str))
            return str;
        byte[] b = str.getBytes();
        if (b.length <= length)
        {
            return str;
        }
        byte[] c = ArrayUtils.subarray(b, 0, length);
        return new String(c);
    }

    public static int getLength(String value)
    {
        if (Strings.isNullOrEmpty(value))
        {
            return 0;
        }

        return value.length();
    }

    public static boolean match(String value, String regex)
    {
        if (Strings.isNullOrEmpty(value))
        {
            return false;
        }
        return Pattern.matches(regex, value);
    }

    public static <T extends Enum<T>> T matchEnumWithCheck(Class<T> enumType,
            String name)
    {
        T rslt = null;
        try
        {
            rslt = Enum.valueOf(enumType, name);
        }
        catch (Throwable e)
        {
            throw new StandardException("0","值无法匹配[" + name + "]",null);
        }
        return rslt;
    }

    public static <T extends Enum<T>> T matchEnumWithoutCheck(Class<T> enumType,
            String name)
    {

        if (Strings.isNullOrEmpty(name))
        {
            return null;
        }

        T rslt = null;
        try
        {
            rslt = Enum.valueOf(enumType, name);
        }
        catch (Throwable e)
        {
        }
        return rslt;
    }

    public static <T extends Enum<T>> T matchEnum(Class<T> enumType,
            String name, T defaultVal)
    {
        T rslt = null;
        try
        {
            rslt = Enum.valueOf(enumType, name);
        }
        catch (Throwable e)
        {
        }
        if (rslt == null)
        {
            rslt = defaultVal;
        }
        return rslt;
    }

    public static String intToZH(int i)
    {
        String[] zh =
        { "零", "一", "二", "三", "四", "五", "六", "七", "八", "九" };
        String[] unit =
        { "", "十", "百", "千", "万", "十", "百", "千", "亿", "十" };

        String str = "";
        StringBuffer sb = new StringBuffer(String.valueOf(i));
        sb = sb.reverse();
        int r = 0;
        int l = 0;
        for (int j = 0; j < sb.length(); j++)
        {
            /**
             * 当前数字
             */
            r = Integer.valueOf(sb.substring(j, j + 1));

            if (j != 0)
                /**
                 * 上一个数字
                 */
                l = Integer.valueOf(sb.substring(j - 1, j));

            if (j == 0)
            {
                if (r != 0 || sb.length() == 1)
                    str = zh[r];
                continue;
            }

            if (j == 1 || j == 2 || j == 3 || j == 5 || j == 6 || j == 7
                    || j == 9)
            {
                if (j == 1 && r == 1)
                {
                    str = unit[j] + str;
                    continue;
                }
                if (r != 0)
                    str = zh[r] + unit[j] + str;
                else if (l != 0)
                    str = zh[r] + str;
                continue;
            }

            if (j == 4 || j == 8)
            {
                str = unit[j] + str;
                if ((l != 0 && r == 0) || r != 0)
                    str = zh[r] + str;
                continue;
            }
        }
        return str;
    }

    public static int compare(String a, String b)
    {
        if (a == null && b == null)
        {
            return 0;
        }
        if (a == null)
        {
            return -1;
        }
        if (b == null)
        {
            return 1;
        }

        return a.compareTo(b);
    }

    public static int getChineseLength(String str)
    {
        if (StringUtils.isEmpty(str))
        {
            return 0;
        }

        int length = 0;

        for (int i = 0; i < str.length(); i++)
        {
            if (String.valueOf(str.charAt(i)).getBytes().length > 1)
            {
                length++;
            }
        }

        return length;
    }

    public static boolean include(String value, String range)
    {
        if (StringUtils.isEmpty(range))
            return false;
        if (StringUtils.isEmpty(value))
            return false;

        List<String> rangeList = Splitter.on(',').trimResults()
                .omitEmptyStrings().splitToList(range);
        return rangeList.contains(value);
    }

    public static List<String> splitByMaxLength(String value, int maxLength)
    {
        List<String> result = Lists.newArrayList();
        if (StringUtils.isEmpty(value) || maxLength <= 0)
        {
            result.add(value);
            return result;
        }
        String retain = value;
        while (StringUtils.length(retain) > maxLength)
        {
            String s = StringUtils.substring(retain, 0,  maxLength);
            retain = StringUtils.substring(retain, maxLength);
            result.add(s);
        }
        
        if(StringUtils.length(retain) >0){
            result.add(retain);
        }

        return result;

    }
}
